package com.helloUIBinder.client.widgets;

import com.google.gwt.cell.client.DateCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.*;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.SingleSelectionModel;
import com.helloUIBinder.client.ProjectJsonParser;
import com.helloUIBinder.client.customComponents.DeleteDialogBox;
import com.helloUIBinder.client.customComponents.EditDeleteCell;
import com.helloUIBinder.client.events.OnAdminBlogPostAddClickEvent;
import com.helloUIBinder.client.events.OnAdminBlogPostTableClickEvent;
import com.helloUIBinder.client.events.OnEditDeleteCellClickEvent;
import com.helloUIBinder.client.events.OnEditDeleteCellClickHandler;
import com.helloUIBinder.client.receivers.BlogPostReceiver;
import com.helloUIBinder.model.BlogPost;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class AdminBlogPostTableWidget extends Composite {

    private static AdminBlogPostTableWidgetUiBinder uiBinder = GWT.create(AdminBlogPostTableWidgetUiBinder.class);

    interface AdminBlogPostTableWidgetUiBinder extends UiBinder<Widget, AdminBlogPostTableWidget> {
    }

    @UiField
    CellTable<BlogPost> cellTable;

    //    @UiField
    SimplePager pager;

    @UiField
    HTMLPanel pagerContainer;

    private ColumnSortList.ColumnSortInfo currentSortedRow;

    private List<String> columnNames = new ArrayList<String>();

    @UiField
    Button addButton;

    private SimpleEventBus eventBus;

    private DeleteDialogBox deleteDialog = new DeleteDialogBox();

    private AsyncDataProvider<BlogPost> dataProvider;
    private SingleSelectionModel<BlogPost> selectionModel = new SingleSelectionModel<BlogPost>();

    public AdminBlogPostTableWidget(SimpleEventBus eventBus) {
        initWidget(uiBinder.createAndBindUi(this));
        this.eventBus = eventBus;
        initBlogPostTable();
        addButton.setText("add Blog");
        pager = new SimplePager() {
            @Override
            public void setPageStart(int index) {
                if (getDisplay() != null) {
                    Range range = getDisplay().getVisibleRange();
                    int pageSize = range.getLength();
                    index = Math.max(0, index);
                    if (index != range.getStart()) {
                        getDisplay().setVisibleRange(index, pageSize);
                    }
                }
            }
        };
        pager.setStyleName("pager-align");
        pagerContainer.add(pager);

        addButton.addClickHandler(new

                ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        OnAdminBlogPostAddClickEvent addClickEvent = new OnAdminBlogPostAddClickEvent();
                        AdminBlogPostTableWidget.this.eventBus.fireEvent(addClickEvent);
                    }
                }

        );

        eventBus.addHandler(OnEditDeleteCellClickEvent.TYPE, new OnEditDeleteCellClickHandler() {
            @Override
            public void click(OnEditDeleteCellClickEvent event) {
                if (event.getClickedButton().equals(OnEditDeleteCellClickEvent.EDIT)) {
                    BlogPost clickedBlogPost = selectionModel.getSelectedObject();
                    OnAdminBlogPostTableClickEvent clickEvent = new OnAdminBlogPostTableClickEvent();
                    clickEvent.setCurrentAction(OnAdminBlogPostTableClickEvent.EDIT);
                    clickEvent.setClickedBlogPost(clickedBlogPost);
                    AdminBlogPostTableWidget.this.eventBus.fireEvent(clickEvent);
                }
                if (event.getClickedButton().equals(OnEditDeleteCellClickEvent.DELETE)) {
                    deleteDialog.center();
                    deleteDialog.getCloseButton().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                            deleteDialog.hide();
                        }
                    });
                    deleteDialog.getOkButton().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                            BlogPost clickedBlogPost = selectionModel.getSelectedObject();
                            OnAdminBlogPostTableClickEvent clickEvent = new OnAdminBlogPostTableClickEvent();
                            clickEvent.setCurrentAction(OnAdminBlogPostTableClickEvent.DELETE);
                            clickEvent.setClickedBlogPost(clickedBlogPost);
                            AdminBlogPostTableWidget.this.eventBus.fireEvent(clickEvent);
                            deleteDialog.hide();
                        }
                    });
                }
            }
        }

        );
    }

    public void refreshTable() {
        BlogPostReceiver.getAllBlogPostsSize(new RequestCallback() {
            @Override
            public void onResponseReceived(Request request, Response response) {

                dataProvider.updateRowCount(Integer.parseInt(response.getText()), true);

                RequestCallback callback = new RequestCallback() {
                    @Override
                    public void onResponseReceived(Request request, Response response) {
                        dataProvider.updateRowData(0, ProjectJsonParser.parseJsonArray(BlogPost.class, response.getText()));
                    }

                    @Override
                    public void onError(Request request, Throwable exception) {
                        Window.alert("Error occurred" + exception.getMessage());
                    }
                };

                final ColumnSortList sortList = cellTable.getColumnSortList();
                String sortColumnName = "";
                String sortOrder = "";
                if (sortList.size() > 0) {
                    Column<BlogPost, ?> sortColumn = (Column<BlogPost, ?>) sortList.get(0).getColumn();
                    Integer columnIndex = cellTable.getColumnIndex(sortColumn);
                    sortColumnName = columnNames.get(columnIndex);
                    if (sortList.get(0).isAscending()) {
                        sortOrder = "ASC";
                    } else {
                        sortOrder = "DESC";
                    }
                }

                if (sortColumnName.equals("Theme")) {
                    BlogPostReceiver.findAllBlogPostsByPage(callback, 0, 15, "theme", sortOrder);
                }
                if (sortColumnName.equals("Owner")) {
                    BlogPostReceiver.findAllBlogPostsByPage(callback, 0, 15, "owner", sortOrder);
                }
                if (sortColumnName.equals("")) {
                    BlogPostReceiver.findAllBlogPostsByPage(callback, 0, 15, null, null);
                }

            }

            @Override
            public void onError(Request request, Throwable exception) {
                Window.alert("Error occurred" + exception.getMessage());
            }
        });
    }

    private void initBlogPostTable() {
        initColumn();


        cellTable.setKeyboardSelectionPolicy(HasKeyboardSelectionPolicy.KeyboardSelectionPolicy.DISABLED);
        cellTable.setPageSize(15);

        cellTable.setSelectionModel(selectionModel);

        BlogPostReceiver.getAllBlogPostsSize(new RequestCallback() {
            @Override
            public void onResponseReceived(Request request, Response response) {

                dataProvider = new AsyncDataProvider<BlogPost>() {
                    @Override
                    protected void onRangeChanged(HasData<BlogPost> display) {

                        final ColumnSortList sortList = cellTable.getColumnSortList();
                        String sortColumnName = "";
                        String sortOrder = "";
                        if (sortList.size() > 0) {
                            Column<BlogPost, ?> sortColumn = (Column<BlogPost, ?>) sortList.get(0).getColumn();
                            Integer columnIndex = cellTable.getColumnIndex(sortColumn);
                            sortColumnName = columnNames.get(columnIndex);
                            if (sortList.get(0).isAscending()) {
                                sortOrder = "ASC";
                            } else {
                                sortOrder = "DESC";
                            }
                        }

                        final int start = display.getVisibleRange().getStart();
                        RequestCallback callback = new RequestCallback() {
                            @Override
                            public void onResponseReceived(Request request, Response response) {
                                updateRowData(start, ProjectJsonParser.parseJsonArray(BlogPost.class, response.getText()));
                            }

                            @Override
                            public void onError(Request request, Throwable exception) {
                                Window.alert("Error occurred" + exception.getMessage());
                            }
                        };

                        Integer page = ((start + 1) / 15);

                        if (sortColumnName.equals("Theme")) {
                            BlogPostReceiver.findAllBlogPostsByPage(callback, page, 15, "theme", sortOrder);
                        }
                        if (sortColumnName.equals("Owner")) {
                            BlogPostReceiver.findAllBlogPostsByPage(callback, page, 15, "owner", sortOrder);
                        }
                        if (sortColumnName.equals("")) {
                            BlogPostReceiver.findAllBlogPostsByPage(callback, page, 15, null, null);
                        }

                    }
                };
                dataProvider.updateRowCount(Integer.parseInt(response.getText()), true);
                dataProvider.addDataDisplay(cellTable);

                pager.setDisplay(cellTable);
                pager.setRangeLimited(true);
            }

            @Override
            public void onError(Request request, Throwable exception) {
                Window.alert("Error occurred" + exception.getMessage());
            }
        });

    }

    private void initColumn() {
        TextColumn<BlogPost> themeColumn = new TextColumn<BlogPost>() {
            @Override
            public String getValue(BlogPost object) {
                return object.getTheme();
            }
        };
        themeColumn.setSortable(true);
        cellTable.addColumn(themeColumn, "Theme");
        columnNames.add("Theme");
        cellTable.setColumnWidth(themeColumn, 20, Style.Unit.PCT);

        TextColumn<BlogPost> categoryColumn =
                new TextColumn<BlogPost>() {
                    @Override
                    public String getValue(BlogPost object) {
                        return object.getCategory();
                    }
                };
        cellTable.addColumn(categoryColumn, "Category");
        columnNames.add("Category");
        cellTable.setColumnWidth(categoryColumn, 20, Style.Unit.PCT);


        TextColumn<BlogPost> ownerColumn =
                new TextColumn<BlogPost>() {
                    @Override
                    public String getValue(BlogPost object) {
                        return object.getOwner();
                    }
                };
        cellTable.addColumn(ownerColumn, "Owner");
        columnNames.add("Owner");
        cellTable.setColumnWidth(ownerColumn, 20, Style.Unit.PCT);


        DateCell dateCell = new DateCell();
        Column<BlogPost, Date> dateColumn
                = new Column<BlogPost, Date>(dateCell) {
            @Override
            public Date getValue(BlogPost object) {
                return object.getDate();
            }
        };
        cellTable.addColumn(dateColumn, "Date");
        columnNames.add("Date");
        cellTable.setColumnWidth(dateColumn, 20, Style.Unit.PCT);

        Column<BlogPost, String> customColumn = new Column<BlogPost, String>(new EditDeleteCell(eventBus)) {
            @Override
            public String getValue(BlogPost object) {
                return String.valueOf(object.getId());
            }
        };
        cellTable.addColumn(customColumn, "customColumn");
        columnNames.add("customColumn");
        cellTable.setColumnWidth(customColumn, 20, Style.Unit.PCT);

        themeColumn.setSortable(true);
        ownerColumn.setSortable(true);
        ColumnSortEvent.AsyncHandler columnSortHandler = new ColumnSortEvent.AsyncHandler(cellTable);
        cellTable.addColumnSortHandler(columnSortHandler);
//        cellTable.getColumnSortList().push(themeColumn);
//        cellTable.getColumnSortList().push(ownerColumn);

    }
}
